<template>
  <div
    :class="['container', { 'alternate-theme': isAlternateTheme }]"
    :style="{
      backgroundImage: `url(${selectedBackground})`,
      backgroundSize: 'cover',
      backgroundPosition: 'center',
      backgroundRepeat: 'no-repeat',
    }"
  >
    <div :class="['sidebar', { 'alternate-theme': isAlternateTheme }]">
      <h3>会话列表</h3>
      <t-list class="conversation-list">
        <t-list-item v-for="(conv, idx) in conversationList" :key="conv.id"
          :class="['conversation-item', { 'active-conversation': idx === activeConversationIndex }]">
          <div class="list-item-content" @click="selectConversation(idx)">
            <t-list-item-meta
              :title = 'conv.name'
              :description="firstUserQuestion(conv.chatHistory)"
            />
          </div>
          <div class="list-item-delete">
            <t-button variant="text" shape="square" @click.stop="deleteConversation(idx)" title="删除会话">
              <DeleteIcon />
            </t-button>
          </div>
        </t-list-item>
      </t-list>
      <t-button @click="createNewConversation" class="create-conv-button">+ 新建会话</t-button>
    </div>
    <div class="main-content">
      <header class="header">
        <div class="header-actions">
          <t-button @click="toggleTheme">切换主题</t-button>
          <t-button @click="showSearchModal = true">搜索消息</t-button>
          <t-button variant="outline" @click="openDownloadModal">下载对话</t-button>
          <t-button variant="outline" @click="openShareModal">分享对话</t-button>
        </div>
      </header>
      <div class="chat-container">
        <t-chat ref="chatRef" layout="single" style="height: 740px"
          :clear-history="chatList.length > 0 && !isStreamLoad" @clear="clearConfirm">
          <template v-for="(item, index) in chatList" :key="index">
            <t-chat-item :avatar="item.avatar" :name="item.name" :role="item.role" :datetime="item.datetime"
              :text-loading="index === 0 && loading">
              <template #content>
                <div :class="['chat-bubble', item.role === 'user' ? 'user-bubble' : 'assistant-bubble']"
                  v-html="parseLatex(item.content)"></div>
              </template>
              <template #actions>
                <div class="custom-action-container">
                  <t-chat-action :is-good="isGood[index]" :is-bad="isBad[index]" :content="item.content"
                    @operation="(type, { e }) => handleOperation(type, { e, index })" class="custom-action-buttons" />
                  <t-button variant="outline" @click="confirmDelete(index)" class="delete-icon-button" title="删除"
                    aria-label="删除消息">
                    <template #icon>
                      <DeleteIcon />
                    </template>
                  </t-button>
                  <t-button variant="outline" @click="quoteMessage(index)" class="quote-icon-button" title="引用"
                    aria-label="引用消息">
                    <template #icon>
                      <ChatIcon />
                    </template>
                  </t-button>
                </div>
              </template>
            </t-chat-item>
          </template>
          <template #footer>
            <div class="chat-input">
              <t-chat-input :value="inputValue" @update:value="val => inputValue = val" :stop-disabled="isStreamLoad"
                @send="inputEnter" @stop="onStop"> </t-chat-input>
            </div>
          </template>
        </t-chat>
        <t-dialog v-model:visible="showFeedbackForm" title="反馈信息" :mask-closable="false" :show-close="false"
          width="500px">
          <div>
            <p>您的操作是：<strong>{{ feedbackType === 'good' ? '点赞' : '点踩' }}</strong></p>
            <p>您对这条消息的评价是：</p>
            <t-textarea v-model="feedbackContent" placeholder="请输入您的反馈（可选）" :rows="4" />
          </div>
          <template #footer>
            <t-button @click="closeFeedbackForm">取消</t-button>
            <t-button type="primary" @click="submitFeedback">提交</t-button>
          </template>
        </t-dialog>
        <t-dialog v-model:visible="showDownloadModal" title="下载对话" :mask-closable="false" :show-close="true"
          width="400px">
          <div>
            <p>请选择下载格式：</p>
            <t-radio-group v-model="downloadFormat">
              <t-radio :value="'markdown'">Markdown</t-radio>
              <t-radio :value="'pdf'">PDF</t-radio>
              <t-radio :value="'word'">Word</t-radio>
              <t-radio value="csv">CSV</t-radio>
              <t-radio value="html">HTML</t-radio>
              <t-radio value="image">长图</t-radio>
            </t-radio-group>
          </div>
          <template #footer>
            <t-button @click="closeDownloadModal">取消</t-button>
            <t-button type="primary" @click="downloadSelectedFormat">下载</t-button>
          </template>
        </t-dialog>
        <t-dialog v-model:visible="showShareModal" title="分享对话" :mask-closable="true" :show-close="true" width="400px">
          <div>
            <p>请选择分享平台：</p>
            <t-radio-group v-model="sharePlatform">
              <t-radio :value="'qq-zero'">QQ空间</t-radio>
              <t-radio :value="'circle'">朋友圈</t-radio>
              <t-radio :value="'cloud'">腾讯云社区</t-radio>
              <t-radio :value="'qq'">QQ好友</t-radio>
              <t-radio :value="'wechat'">微信好友</t-radio>
              <t-radio :value="'qy-wechat'">企业微信</t-radio>
              <t-radio :value="'email'">QQ邮箱</t-radio>
              <t-radio :value="'channel'">QQ频道</t-radio>
              <t-radio :value="'small-world'">QQ小世界</t-radio>
            </t-radio-group>
          </div>
          <template #footer>
            <t-button @click="closeShareModal">取消</t-button>
            <t-button type="primary" @click="handleShareSuccess">分享</t-button>
          </template>
        </t-dialog>
        <t-dialog v-model:visible="showDeleteConfirm" title="确认删除" :mask-closable="false" :show-close="false"
          width="400px">
          <div>
            <p>您确定要删除这条消息吗？</p>
          </div>
          <template #footer>
            <t-button @click="cancelDelete">取消</t-button>
            <t-button type="primary" @click="confirmDeleteMessage">确认删除</t-button>
          </template>
        </t-dialog>
        <t-dialog v-model:visible="showSearchModal" title="搜索消息" width="600px">
          <!-- 搜索输入 -->
          <div class="search-bar">
            <t-input v-model="searchQuery" placeholder="请输入搜索关键字" clearable @enter="handleSearch" />
            <t-button theme="primary" @click="handleSearch" style="margin-left: 8px;">
              搜索
            </t-button>
          </div>

          <!-- 搜索结果展示 -->
          <div class="search-result-list" v-if="searchResults.length">
            <p>共找到 {{ searchResults.length }} 条匹配：</p>
            <ul>
              <li v-for="result in searchResults" :key="result.messageId" @click="jumpToMessage(result.messageId)"
                class="search-result-item">
                <p class="search-result-text" v-html="result.snippet"></p>
                <p class="search-result-info">
                  来自：{{ result.name }} | 时间：{{ result.datetime }}
                </p>
              </li>
            </ul>
          </div>

          <template #footer>
            <t-button theme="default" @click="showSearchModal = false">关闭</t-button>
          </template>
        </t-dialog>

      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted, watch } from 'vue';
import { MessagePlugin } from 'tdesign-vue-next';
import { saveAs } from 'file-saver';
import { DeleteIcon, ChatIcon } from 'tdesign-icons-vue-next';
import html2pdf from 'html2pdf.js';
import html2canvas from 'html2canvas';

const showDeleteConfirm = ref(false);
const deleteIndex = ref(null);

const selectedBackground = ref('');

const showSearchModal = ref(false);
const searchQuery = ref('');
const searchResults = ref([]);

const bgImages = [
  'https://www.helloimg.com/i/2025/01/13/67843117f1303.png',
  'https://www.helloimg.com/i/2025/01/13/6784311805db5.png',
  'https://www.helloimg.com/i/2025/01/13/678431184d457.png',
];

const handleSearch = () => {
  if (!searchQuery.value.trim()) {
    searchResults.value = [];
    return;
  }
  const keyword = searchQuery.value.trim();
  searchResults.value = [];
  chatList.value.forEach((msg) => {
    msg.highlightedContent = null;
    const contentLower = msg.content.toLowerCase();
    const keywordLower = keyword.toLowerCase();
    const index = contentLower.indexOf(keywordLower);
    if (index !== -1) {
      const highlighted = highlightKeyword(msg.content, keyword);
      msg.highlightedContent = highlighted;
      const snippet = createSnippet(msg.content, index, keyword.length);
      searchResults.value.push({
        messageId: msg.id,
        name: msg.name,
        datetime: msg.datetime,
        snippet: highlightKeyword(snippet, keyword),
      });
    }
  });
};

function highlightKeyword(text, keyword) {
  const regex = new RegExp(keyword, 'gi');
  return text.replace(regex, (match) => `<mark>${match}</mark>`);
}

function createSnippet(text, index, keywordLen) {
  const snippetLength = 30;
  const start = Math.max(0, index - snippetLength);
  const end = Math.min(text.length, index + keywordLen + snippetLength);
  let snippet = text.substring(start, end);
  if (start > 0) {
    snippet = '...' + snippet;
  }
  if (end < text.length) {
    snippet += '...';
  }
  return snippet;
}

const jumpToMessage = async (messageId) => {
  await nextTick();
  const el = document.getElementById(`msg-${messageId}`);
  if (el) {
    el.scrollIntoView({ behavior: 'smooth', block: 'center' });
  }
};

const downloadAsWord = () => {
  const conversationHtml = chatList.value
    .map((msg) => {
      const time = new Date(msg.datetime).toLocaleString();
      const content = msg.content.replace(/<[^>]+>/g, '');
      return `<p><strong>[${time}] ${msg.name} (${msg.role}):</strong> ${content}</p>`;
    })
    .reverse()
    .join('');
  const htmlContent = `
    <html>
      <head>
        <meta charset="utf-8" />
        <title>对话记录</title>
      </head>
      <body>
        ${conversationHtml}
      </body>
    </html>
  `;
  const blob = new Blob([htmlContent], {
    type: 'application/msword;charset=utf-8'
  });
  saveAs(blob, 'conversation.doc');
};

const removeMarkdownSymbols = (text) => {
  return text
    .replace(/(\*\*|__)(.*?)\1/g, '$2')
    .replace(/(\*|_)(.*?)\1/g, '$2')
    .replace(/`{1,3}(.*?)`{1,3}/g, '$1')
    .replace(/!\[.*?\]\(.*?\)/g, '')
    .replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')
    .replace(/#+\s*(.*)/g, '$1')
    .replace(/>\s*(.*)/g, '$1')
    .replace(/-\s*(.*)/g, '$1')
    .replace(/\d+\.\s*(.*)/g, '$1')
    .replace(/\n{2,}/g, '\n');
};

const showFeedbackForm = ref(false);
const feedbackType = ref(null);
const currentFeedbackIndex = ref(null);
const feedbackContent = ref('');
const showShareModal = ref(false);
const sharePlatform = ref('wechat');
const showDownloadModal = ref(false);
const downloadFormat = ref('markdown');
const chatRef = ref(null);
const isAlternateTheme = ref(false);

const toggleTheme = () => {
  isAlternateTheme.value = !isAlternateTheme.value;
  const randomIndex = Math.floor(Math.random() * bgImages.length);
  selectedBackground.value = bgImages[randomIndex];
};

const openDownloadModal = () => {
  showDownloadModal.value = true;
};

const closeDownloadModal = () => {
  showDownloadModal.value = false;
};

const openShareModal = () => {
  showShareModal.value = true;
};

const closeShareModal = () => {
  showShareModal.value = false;
};

const handleShareSuccess = () => {
  closeShareModal();
  MessagePlugin.success('分享成功！');
};

const downloadSelectedFormat = () => {
  switch (downloadFormat.value) {
    case 'markdown': downloadAsMarkdown(); break;
    case 'pdf': downloadAsPDF(); break;
    case 'word': downloadAsWord(); break;
    case 'csv': downloadAsCSV(); break;
    case 'html': downloadAsHTML(); break;
    case 'image': downloadAsImage(); break;
  }
  closeDownloadModal();
};

const downloadAsMarkdown = () => {
  const markdownContent = chatList.value
    .map(msg => {
      const time = new Date(msg.datetime).toLocaleString();
      const content = msg.content.replace(/<[^>]+>/g, '');
      return `**[${time}] ${msg.name} (${msg.role})**\n\n${content}\n`;
    })
    .reverse()
    .join('\n\n');
  const blob = new Blob([markdownContent], { type: 'text/markdown;charset=utf-8' });
  saveAs(blob, 'conversation.md');
};

const downloadAsPDF = () => {
  const element = document.querySelector('.t-chat');

  const opt = {
    margin: 1,
    filename: 'conversation.pdf',
    image: { type: 'jpeg', quality: 0.98 },
    html2canvas: { scale: 2 },
    jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
  };
  html2pdf().from(element).set(opt).save();
};

const backBottom = () => {
  chatRef.value.scrollToBottom({
    behavior: 'smooth',
  });
};

const chatList = ref([
  {
    avatar: 'https://www.helloimg.com/i/2025/01/13/678437126cd1c.jpg',
    name: '高数专家',
    datetime: new Date().toLocaleString(),
    content: '你好！我是高数专家，很高兴为你提供帮助，你可以问我各种数学题目。',
    role: 'assistant',
  },
]);

const isGood = ref([]);
const isBad = ref([]);

const initializeFeedbackStates = () => {
  isGood.value = chatList.value.map(() => false);
  isBad.value = chatList.value.map(() => false);
};

initializeFeedbackStates();

const fetchCancel = ref(null);
const loading = ref(false);
const isStreamLoad = ref(false);

const clearConfirm = function () {
  chatList.value = [];
  initializeFeedbackStates();
};

const onStop = function () {
  if (fetchCancel.value) {
    fetchCancel.value.abort();
    loading.value = false;
    isStreamLoad.value = false;
  }
};

const handleOperation = function (type, options) {
  const { index } = options;
  if (type === 'good') {
    isGood.value[index] = !isGood.value[index];
    if (isGood.value[index]) {
      isBad.value[index] = false;
      feedbackType.value = 'good';
      currentFeedbackIndex.value = index;
      showFeedbackForm.value = true;
    }
  } else if (type === 'bad') {
    isBad.value[index] = !isBad.value[index];
    if (isBad.value[index]) {
      isGood.value[index] = false;
      feedbackType.value = 'bad';
      currentFeedbackIndex.value = index;
      showFeedbackForm.value = true;
    }
  } else if (type === 'replay') {
    const userQuery = chatList.value[index + 1].content;
    inputEnter(userQuery);
  }
};

const submitFeedback = () => {
  if (currentFeedbackIndex.value === null) {
    MessagePlugin.error('未找到对应的消息！');
    return;
  }
  MessagePlugin.info('提交成功，我们将根据你的反馈对后面的内容进行调整！');
  showFeedbackForm.value = false;
};

const closeFeedbackForm = () => {
  showFeedbackForm.value = false;
};

const handleData = async (inputValue) => {
  loading.value = true;
  isStreamLoad.value = true;
  const lastItem = chatList.value[0];
  const messages = [
    { role: 'system', content: '你是一个高等数学老师，你有丰富的教学经验，你总能一针见血告诉学生关键的思路并给出题目的标准答案。', },
    { role: 'user', content: inputValue, }
  ];
  fetchSSE(messages, {
    success(result) {
      loading.value = false;
      const { data } = result;
      const cleanedContent = removeMarkdownSymbols(data?.delta?.content || '');
      lastItem.content += cleanedContent;
    },
    complete(isOk, msg) {
      if (!isOk || !lastItem.content) {
        lastItem.role = 'error';
        lastItem.content = msg;
      }
      isStreamLoad.value = false;
      loading.value = false;
    },
    cancel(cancel) {
      fetchCancel.value = cancel;
    },
  });
};

const inputEnter = function (inputValue) {
  if (isStreamLoad.value) {
    return;
  }
  if (!inputValue) return;
  const modifiedInput = `${inputValue}`;
  const params = {
    avatar: 'https://www.helloimg.com/i/2025/01/13/6784383e4b6c5.jpg',
    name: '我',
    datetime: new Date().toLocaleString(),
    content: `${inputValue}`,
    role: 'user',
  };
  chatList.value.unshift(params);
  const params2 = {
    avatar: 'https://www.helloimg.com/i/2025/01/13/678437126cd1c.jpg',
    name: '高数专家',
    datetime: new Date().toLocaleString(),
    content: '',
    role: 'assistant',
  };
  chatList.value.unshift(params2);
  isGood.value.unshift(false);
  isBad.value.unshift(false);
  handleData(modifiedInput);
};

const fetchSSE = async (messages, options) => {
  const { success, fail, complete, cancel } = options;
  const controller = new AbortController();
  const { signal } = controller;
  cancel?.(controller);
  const apiKey = 'sk-6R0hq8U7v3bSbT1u41Lp6kPRwAgf9wnW73WgvSC7WUI73eRO';
  const responsePromise = fetch('/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer${apiKey ? ` ${apiKey}` : ''}`,
    },
    body: JSON.stringify({
      messages,
      model: 'hunyuan-pro',
      stream: true,
    }),
    signal,
  }).catch((e) => {
    const msg = e.toString() || '流式接口异常';
    complete?.(false, msg);
    return Promise.reject(e);
  });
  responsePromise
    .then((response) => {
      if (!response?.ok) {
        complete?.(false, response.statusText);
        fail?.();
        throw new Error('Request failed');
      }
      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      if (!reader) throw new Error('No reader available');
      const bufferArr = [];
      let dataText = '';
      const event = { type: null, data: null };
      async function processText({ done, value }) {
        if (done) {
          complete?.(true);
          return Promise.resolve();
        }
        const chunk = decoder.decode(value);
        const buffers = chunk.toString().split(/\r?\n/);
        bufferArr.push(...buffers);
        let i = 0;
        while (i < bufferArr.length) {
          const line = bufferArr[i];
          if (line) {
            dataText += line;
            const response = line.slice(6);
            if (response === '[DONE]') {
              event.type = 'finish';
              dataText = '';
            } else {
              const choices = JSON.parse(response.trim())?.choices?.[0];
              if (choices.finish_reason === 'stop') {
                event.type = 'finish';
                dataText = '';
              } else {
                event.type = 'delta';
                event.data = choices;
              }
            }
          }
          if (event.type && event.data) {
            const jsonData = JSON.parse(JSON.stringify(event));
            success(jsonData);
            event.type = null;
            event.data = null;
          }
          bufferArr.splice(i, 1);
        }
        return reader.read().then(processText);
      }
      return reader.read().then(processText);
    })
    .catch(() => {
      fail?.();
    });
};

const deleteConversation = (index) => {
  if (index === activeConversationIndex.value) {
    conversationList.value.splice(index, 1);
    if (conversationList.value.length > 0) {
      activeConversationIndex.value = 0;
      loadConversation(0);
    } else {
      createNewConversation();
    }
  } else {
    conversationList.value.splice(index, 1);
    if (index < activeConversationIndex.value) {
      activeConversationIndex.value--;
    }
  }
};

const confirmDelete = (index) => {
  deleteIndex.value = index;
  showDeleteConfirm.value = true;
};

const confirmDeleteMessage = () => {
  if (deleteIndex.value !== null) {
    chatList.value.splice(deleteIndex.value, 1);
    isGood.value.splice(deleteIndex.value, 1);
    isBad.value.splice(deleteIndex.value, 1);
    MessagePlugin.success('消息已删除');
    deleteIndex.value = null;
    showDeleteConfirm.value = false;
  }
};

const cancelDelete = () => {
  deleteIndex.value = null;
  showDeleteConfirm.value = false;
};

const inputValue = ref('');

const quoteMessage = (index) => {
  const quotedContent = chatList.value[index].content;
  inputValue.value = `> ${quotedContent}`;
};

const downloadAsCSV = () => {
  let csvContent = '时间,发送者,角色,内容\n';
  chatList.value
    .slice()
    .reverse()
    .forEach(msg => {
      const time = new Date(msg.datetime).toLocaleString();
      const content = msg.content.replace(/<[^>]+>/g, '');
      const row = `"${time}","${msg.name}","${msg.role}","${content.replace(/"/g, '""')}"`;
      csvContent += row + '\n';
    });
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  saveAs(blob, 'conversation.csv');
};

const downloadAsHTML = () => {
  const conversationHtml = chatList.value
    .map((msg) => {
      const time = new Date(msg.datetime).toLocaleString();
      const content = msg.content;
      return `<div style="margin-bottom: 1em;">
        <strong>[${time}] ${msg.name} (${msg.role})</strong><br>
        <div>${content}</div>
      </div>`;
    })
    .reverse()
    .join('');
  const htmlContent = `
    <html>
      <head>
        <meta charset="utf-8" />
        <title>对话记录</title>
      </head>
      <body>
        ${conversationHtml}
      </body>
    </html>
  `;
  const blob = new Blob([htmlContent], { type: 'text/html;charset=utf-8' });
  saveAs(blob, 'conversation.html');
};

const downloadAsImage = async () => {
  const element = document.querySelector('.t-chat');
  if (!element) {
    console.error('未找到.t-chat');
    return;
  }
  try {
    const canvas = await html2canvas(element, {
      scale: 2,
    });
    const dataURL = canvas.toDataURL('image/png');
    const link = document.createElement('a');
    link.href = dataURL;
    link.download = 'conversation.png';
    link.click();
  } catch (error) {
    console.error('长图截取失败:', error);
  }
};

const conversationList = ref([]);

const activeConversationIndex = ref(0);

onMounted(() => {
  const randomIndex = Math.floor(Math.random() * bgImages.length);
  selectedBackground.value = bgImages[randomIndex];
  const saved = localStorage.getItem('conversationList');
  if (saved) {
    conversationList.value = JSON.parse(saved);
  }
  if (conversationList.value.length === 0) {
    createNewConversation();
  } else {
    loadConversation(activeConversationIndex.value);
  }
});

watch(conversationList, (newVal) => {
  localStorage.setItem('conversationList', JSON.stringify(newVal));
}, { deep: true });

watch(chatList, (newChatList) => {
  const idx = activeConversationIndex.value;
  if (conversationList.value[idx]) {
    conversationList.value[idx].chatHistory = JSON.parse(JSON.stringify(newChatList));
  }
}, { deep: true });

function createNewConversation() {
  const newConv = {
    id: Date.now(),
    name: '新的会话 ' + new Date().toLocaleTimeString(),
    chatHistory: [
      {
        avatar: 'https://www.helloimg.com/i/2025/01/13/678437126cd1c.jpg',
        name: '高数专家',
        datetime: new Date().toLocaleString(),
        content: '你好！我是一名资深的高等数学老师，有任何数学问题都可以问我。',
        role: 'assistant',
      }
    ],
  };
  conversationList.value.push(newConv);
  activeConversationIndex.value = conversationList.value.length - 1;
  loadConversation(activeConversationIndex.value);
}

function loadConversation(index) {
  if (!conversationList.value[index]) return;
  chatList.value = JSON.parse(JSON.stringify(conversationList.value[index].chatHistory));
  activeConversationIndex.value = index;
}

function selectConversation(index) {
  loadConversation(index);
}

function firstUserQuestion(chatHistory) {
  if (!Array.isArray(chatHistory)) return '';
  const firstUserMsg = chatHistory.find((msg) => msg.role === 'user');
  if (!firstUserMsg?.content) return '';
  return firstUserMsg.content.slice(0, 30);
}

</script>

<script>
import { ref } from 'vue';
import { renderToString } from 'katex';

const parseLatex = (text) => {
  if (!text) return '';
  let blockRegex = /\$\$([^$]+)\$\$/g;
  text = text.replace(blockRegex, (match, group1) => {
    try {
      return renderToString(group1, { displayMode: true });
    } catch (error) {
      console.error('KaTeX block parse error:', error);
      return match;
    }
  });
  let inlineRegex = /\$([^$]+)\$/g;
  text = text.replace(inlineRegex, (match, group1) => {
    try {
      return renderToString(group1, { displayMode: false });
    } catch (error) {
      console.error('KaTeX inline parse error:', error);
      return match;
    }
  });
  return text;
};
</script>
<style scoped>
.container {
  display: flex;
  height: 100vh;
}

.sidebar {
  width: 250px;
  padding: 20px;
  box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  gap: 10px;
  background-color: #fff;
}

.chat-container {
  flex: 1;
  padding: 20px;
  background-color: #e9edf525;
  display: flex;
  flex-direction: column;
}

.chat-bubble {
  max-width: 70%;
  padding: 12px 18px;
  border-radius: 20px;
  margin-bottom: 12px;
  word-wrap: break-word;
  position: relative;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  font-size: 16px;
  line-height: 1.5;
}

.user-bubble {
  background-color: #d1eaff;
  align-self: flex-end;
  border-top-right-radius: 0;
}

.assistant-bubble {
  background-color: #ffffff;
  align-self: flex-start;
  border-top-left-radius: 0;
}

.translate-action {
  margin-top: 5px;
}

.translated-text {
  margin-top: 5px;
  padding: 8px 12px;
  background-color: #f0f4f8;
  border-radius: 10px;
  font-size: 14px;
  color: #333333;
}

.active-good {
  color: #28a745;
}

.active-bad {
  color: #dc3545;
}

.chat-footer {
  display: flex;
  align-items: center;
}

.footer-actions {
  display: flex;
  gap: 8px;
  margin-left: 16px;
}

.t-chat-input__inner {
  border: 2px solid #d083f3;
  border-radius: 10px;
  padding: 10px 15px;
  font-size: 16px;
  background-color: #ffffff;
  height: 100%;
}

.t-chat-input__inner:focus {
  border-color: #bfadf0;
  box-shadow: 0 0 5px rgba(176, 160, 240, 0.5);
}

.sidebar-button {
  margin-top: 10px;
  width: 100%;
}

.custom-action-buttons {
  display: flex;
  gap: 10px;
  justify-content: flex-start;
}

.custom-action-buttons .t-button {
  padding: 6px 12px;
  font-size: 14px;
  border-radius: 8px;
  transition: background-color 0.3s;
}

.custom-action-buttons .t-button:hover {
  background-color: #e0e0e0;
}

.custom-action-buttons .t-button-active {
  background-color: #4caf50;
  color: white;
}

.t-dialog .t-button-primary {
  background-color: #4caf50;
  color: white;
  border-radius: 8px;
}

.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.chat-input {
  position: fixed;
  bottom: 20px;
  left: 310px;
  right: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
  background-color: #ffffffd3;
  padding: 10px;
  border-radius: 20px;
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
  z-index: 1000;
}

.custom-input {
  width: 100%;
  max-width: 500px;
  padding: 10px;
  border-radius: 20px;
  border: 1px solid #ccc;
  font-size: 14px;
}

.send-button {
  padding: 8px 12px;
  border-radius: 20px;
  background-color: #4caf50;
  color: white;
  border: none;
  font-size: 14px;
  cursor: pointer;
}

.send-button:hover {
  background-color: #45a049;
}

.custom-action-container {
  display: flex;
  align-items: center;
  gap: 8px;
}

.delete-button {
  margin-top: 10px;
  width: 100%;
  color: #dc3545;
  border-color: #dc3545;

  &:hover {
    background-color: #f8d7da;
    border-color: #dc3545;
  }
}

.custom-action-container {
  display: flex;
  align-items: center;
  gap: 8px;
}

.delete-icon-button,
.quote-icon-button {
  min-width: 36px;
  padding: 0;
  border-radius: 8px;

  &:hover {
    background-color: #f6f6f6;
  }
}

.delete-icon-button {
  color: #dc3545;
  border: 1px solid #dc3545;
}

.quote-icon-button {
  color: #1890ff;
  border: 1px solid #1890ff;
}

.search-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.search-result-list {
  margin-top: 16px;
  max-height: 300px;
  overflow-y: auto;
}

.search-result-item {
  cursor: pointer;
  margin-bottom: 12px;
  padding: 8px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.search-result-item:hover {
  background-color: #f5f5f5;
}

.search-result-text mark {
  background-color: #ffeb3b;
}

.search-result-info {
  font-size: 12px;
  color: #888;
  margin-top: 4px;
}

.t-switch {
  margin-bottom: 20px;
}

.main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.header {
  height: 60px;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  padding: 0 20px;
  z-index: 1001;
  background-color: #ffffffd3;
}

.header-actions {
  margin-left: auto;
  display: flex;
  gap: 10px;
}

.chat-container {
  flex: 1;
  padding: 20px;
  background-color: #e9edf525;
  display: flex;
  flex-direction: column;
  position: relative;
}

.conversation-list {
  max-height: calc(100vh - 200px);
  overflow-y: auto;
  margin-top: 10px;
}

.conversation-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-right: 8px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.conversation-item:hover {
  background-color: #f6f6f6;
}

.active-conversation {
  background-color: #dde5f2;
  font-weight: bold;
}

.list-item-delete {
  display: flex;
  align-items: center;
}

.create-conv-button {
  margin-top: 10px;
  width: 100%;
}

.conversation-item {
  position: relative;
}

.list-item-delete {
  visibility: hidden;
}

.conversation-item:hover .list-item-delete {
  visibility: visible;
}

.t-list-item {
  padding: 4px 10px 5px 12px;
}

::v-deep .t-list-item__meta-description {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.5; 
  max-height: 3em;
}
</style>